#include "stdafx.h"
#include "Application.h"
#include "MiniDump.h"

void ReadSettings(Graphics::SetupInfo& aGfxSettings, WMInput::Settings& aInputSettings);
std::string GetDumpTimeStamp();

LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	PAINTSTRUCT ps;
	HDC hdc;

	switch( msg )
	{
	case WM_DESTROY:
		PostQuitMessage( 0 );
		break;

	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		EndPaint(hWnd, &ps);
		break;
	}

	if(WMInput::WM_InputWrapper::GetInstance())
	{
		WMInput::WM_InputWrapper::GetInstance()->HandleMessage(hWnd, msg, wParam, lParam);
	}
	
// 	if(msg == WM_KILLFOCUS || msg == WM_SETFOCUS)
// 	{
// 		__asm int 3;
// 	}

	return DefWindowProc( hWnd, msg, wParam, lParam );
}


int WINAPI WinMain(HINSTANCE anHInstance, HINSTANCE aHPrevInstance, LPSTR aCmdLine, int aNumberOfCommands)
{
	DL_Debug::Debug::Create("debug.log", OS::WRITE);
	char appPath[1000];
	//_getcwd(appPath, sizeof(appPath));
	GetModuleFileName(0, appPath, 1000);
	std::string appPathString(appPath);
	DL_PRINT(appPathString);
#ifdef RCBUILD
	DL_Debug::Debug::Log(Utils::Debug::DebugAll, "RC Build");
#else
#ifdef _DEBUG
	DL_Debug::Debug::Log(Utils::Debug::DebugAll, "Full Debug Build");
#else
	DL_Debug::Debug::Log(Utils::Debug::DebugAll, "Debug Release Build");
#endif
#endif
	MiniDumper dumper("The Attic", GetDumpTimeStamp().c_str());
	DL_PRINT("\n--------------------------------------");

	Syncronization::Syncronizer::Create();

	Graphics::SetupInfo gfxSettings;
	gfxSettings.windowProc = MsgProc;
	WMInput::Settings inputSettings;
	ReadSettings(gfxSettings, inputSettings);

	Graphics::Engine::Create(anHInstance, gfxSettings);
	
	inputSettings.appWindow = Graphics::Engine::GetWindow();
	WMInput::WM_InputWrapper::Create(inputSettings);

// 	Clock::TimeManager temp;
// 	temp.InitDefaults();

	Application* theApp = new Application;
	if(theApp->Init() == false)
	{
		DL_CRITICAL("Failed to initialize application, aborting");
		return 1;
	}
	
	MSG msg;
	while(true)
	{
		bool quit = false;
		while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
			{
				quit = true;
				break;
			}
			if(msg.message == WM_KILLFOCUS || msg.message == WM_SETFOCUS)
			{
				__asm int 3;
			}
			//WMInput::WM_InputWrapper::GetInstance()->HandleMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam);

			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}

		if(quit == true)
		{
			break;
		}

		if(theApp->Update() == false)
		{
			break;
		}
	}


	theApp->Destroy();
	delete theApp;
	WMInput::WM_InputWrapper::Destroy();
	Graphics::Engine::GetInstance()->Update(); // To clean up stuff that was deleted when the application was destroyed
	Graphics::Engine::Destroy();
	Syncronization::Syncronizer::Destroy();

	return 0;
}



void ReadSettings(Graphics::SetupInfo& aGfxSettings, WMInput::Settings& aInputSettings)
{
	Utils::DataManager reader;
	reader.AddParameter("resolution", aGfxSettings.resolution);
	reader.AddParameter("windowed", aGfxSettings.windowed);
	reader.AddParameter("windowPosition", aGfxSettings.position);
	reader.AddParameter("windowBorders", aGfxSettings.borders);
	reader.AddParameter("useScissorRectangle", aGfxSettings.useScissorRect);

	reader.AddParameter("useRawInput", aInputSettings.useRawInput);
	reader.AddParameter("showWindowsCursor", aInputSettings.showCursor);
	reader.AddParameter("clipCursorToWindow", aInputSettings.clipCursor);
	
	if(ResourceManager::FileExists("settings.ini") == false)
	{
		DL_DEBUG("\"settings.ini\" could not be found. Proceeding to generate file with default settings");
		reader.WriteData("settings.ini");
		return;
	}

	if(reader.ReadData("settings.ini") == true)
	{
		DL_PRINT("\"settings.ini\" successfully loaded");
	}
	else
	{
		DL_ERROR("Error when reading \"settings.ini\"");
	}
}

std::string GetDumpTimeStamp()
{
	time_t now;
	time(&now);
	char buffer[255];
	tm time;
	localtime_s(&time, &now);
	asctime_s(&buffer[0], 255, &time);
	int i = 0;
	while(buffer[i] != '\0')
	{
		if(buffer[i] == ':')
		{
			buffer[i] = '-';
		}
		i++;
	}
	if(buffer[i - 1] == '\n')
	{
		buffer[i-1] = '\0';
	}

	return std::string(" ") + std::string(buffer);
}